read_character(Char) :- get_single_char(Char).
read_line(String) :- current_input(CommandLine), read_line_to_codes(CommandLine,String).
write_character(Char) :- put_code(Char).
write_string(String) :- maplist(put_code,String).
get_file_contents(Filename, String) :-
  open(Filename, read, Fd),
  get_contents(Fd, String),
  close(Fd).
get_contents(Fd,[]) :- at_end_of_stream(Fd), !.
get_contents(Fd,[C|Cs]) :- get_code(Fd,C), get_contents(Fd,Cs).
open_file(Filename, Read_or_Write, Handle) :-
 atom_codes(FilenameA, Filename),
 open(FilenameA, Read_or_Write, Handle, []).
write_string(_,[]).
write_string(Handle,[C|Cs]) :- put_code(Handle,C), write_string(Handle,Cs).


%% Stuff from book.pl
memq(X,[X1|_]) :- X == X1.
memq(X,[_|Xs]) :- memq(X,Xs).

split([Sep|RHS], Sep, []-RHS).
split([Head|Tail], Sep, [Head|LHS]-RHS) :- split(Tail, Sep, LHS-RHS).

filter(_,[],[]).
filter(E,[E|Es],Fs) :- filter(E,Es,Fs).
filter(E,[F|Es],[F|Fs]) :- E \= F, filter(E,Es,Fs).

sort(Key,List,Sorted) :- qsort(Key,List,Sorted,[]).

qsort(Key,[X|L],R,R0) :-
	partition(Key,L,X,L1,L2),
	qsort(Key,L2,R1,R0),
	qsort(Key,L1,R,[X|R1]).
qsort(_,[],R,R).

partition(Key,[X|L],Y,[X|L1],L2) :-
	apply(Key,[X,Xk]), apply(Key,[Y,Yk]), Xk >= Yk, !,
	partition(Key,L,Y,L1,L2).
partition(Key,[X|L],Y,L1,[X|L2]) :-
	partition(Key,L,Y,L1,L2).
partition(_,[],_,[],[]).

'$foo$expand_term'(Term, Expansion) :- '$foo$term_expansion'(Term, Expansion), !.
'$foo$expand_term'(Term, Term).



boot :-
 consult('dcg.pl'),
 compile_file("BookModule",'book.pl',X), open('BookModule.java',write,H),write_string(H,X),close(H),
 compile_file("JavaGlue",'java.pl',X), open('JavaGlue.java',write,H),write_string(H,X),close(H).
